package game.source.physics;

import java.awt.Point;

/*Classe utilizada para a delimitação da região de colisão*/
class Region{
	private Point startPoint;	//Ponto superior esquerdo
	private Point endPoint;		//Ponto inferior direito
	public Region(){
		this.startPoint = new Point();
		this.endPoint = new Point();
	}

	public void setBounds(int x0, int y0,int x1,int y1){
		this.startPoint.x = x0;
		this.startPoint.y = y0;
		this.endPoint.x = x1;
		this.endPoint.y = y1;
	}

	public int getX0(){
		return this.startPoint.x;
	}

	public int getY0(){
		return this.startPoint.y;
	}

	public int getX1(){
		return this.endPoint.x;
	}

	public int getY1(){
		return this.endPoint.y;
	}

	public int getHeight(){
		return (this.endPoint.y - this.startPoint.y);
	}

	public int getWidth(){
		return (this.endPoint.x - this.startPoint.x);
	}
}

/*Physics:
 * O algoritmo de colisão funciona através da região limitadora das imagens e de seus pixels.
 * Se as regiões se sobrepõem elas são candidatas a colisão, se encontra a região de
 * intersecção e testa se os pixels das imagens nessa região são puramente transparente,
 * caso haja um pixel não transparente é testado se o pixel correspondente na outra imagem
 * também não é transparente, em caso afirmativo houve a colisão. 
 *  
 * 	     x0b________x1b
 * 		   |       B|y0b
 * y0a ____|___	    |
 *    |A   |R  |    |
 *    |	   |___|____|y1b
 *    |        |
 * y1a|________|
 *   x0a	   x1a
 *   
 *   Legenda:
 *   	A - Região da imagem A
 *   	B - Região da imagem B
 *   	R - Região de intersecção
 *   	y0* - posição em y inicial da determinada imagem
 *   	y1* - posição em y final da determinada imagem
 *   	x0* - posição em x inicial da determinada imagem
 *   	x1* - posição em x final da determinada imagem
 *   
 */
public class Physics{
	public static boolean colide(PhysicsObjectInterface A,PhysicsObjectInterface B){
		int x0a = A.getX0();
		int x1a = A.getX0()+A.getWidth();
		int y0a = A.getY0();
		int y1a = A.getY0()+A.getHeight();
		int x0b = B.getX0();
		int x1b = B.getX0()+B.getWidth();
		int y0b = B.getY0();
		int y1b = B.getY0()+B.getHeight();
		Region regionA = new Region();	//Região de intersecção em A
		Region regionB = new Region();	//Região de intersecção em B
		if((y0a > y0b) && (x0a > x0b) && (x1a < x1b) && (y1a < y1b)){
			/*Caso:
			 *  ________________
			 * |B				|
			 * |  __________	|
			 * | |A = R 	|	|
			 * | |			|	|
			 * | |			|	|
			 * | |__________|	|
			 * |________________|
			 * 
			 * */
			regionA.setBounds(0, 0,A.getWidth(), A.getHeight());
			regionB.setBounds(x0a-x0b,y0a-y0b,(x0a-x0b)+A.getWidth(),(y0a-y0b)+A.getHeight());
		}else if((y0a > y0b && y0a < y1b) && (x0a > x0b) && (x1a < x1b) && (y1a >= y1b)){
			/*Caso:
			 *  ________________
			 * |B				|
			 * |  				|
			 * |				|
			 * |  __________	|
			 * | |R		 	|	|
			 * |_|__________|___|
			 *   |			|
			 *   |A			|
			 *   |__________|	
			 * 
			 * */
			regionA.setBounds(0, 0,A.getWidth(), A.getHeight()-(y1a-y1b));
			regionB.setBounds(x0a-x0b,y0a-y0b,(x0a-x0b)+A.getWidth(),(y0a-y0b)+A.getHeight()-(y1a-y1b));
		}else if((y0a > y0b) && (x0a > x0b && x0a < x1b) && (x1a >= x1b) && (y1a < y1b)){
			/*Caso:
			 * 	____________
			 * |B			|
			 * |	   _____|___
			 * |	  |R	|  A|
			 * |	  |		|	|
			 * |	  |_____|___|
			 * |____________|
			 * 
			 * */
			regionA.setBounds(0, 0, A.getWidth()-(x1a-x1b), A.getHeight());
			regionB.setBounds(x0a-x0b,y0a-y0b,(x0a-x0b)+A.getWidth()-(x1a-x1b),(y0a-y0b)+A.getHeight());
		}else if((y0a > y0b && y0a < y1b) && (x0a > x0b && x0a < x1b) && (x1a >= x1b) && (y1a >= y1b)){
			/*Caso:
			 *  ________
			 * |B		|
			 * |	 ___|___
			 * |	|R	|  A|
			 * |	|	|	|
			 * |____|___|	|
			 * 		|		|
			 * 		|_______|
			 * */
			regionA.setBounds(0, 0, A.getWidth()-(x1a-x1b), A.getHeight()-(y1a-y1b));
			regionB.setBounds(x0a-x0b,y0a-y0b,(x0a-x0b)+A.getWidth()-(x1a-x1b),(y0a-y0b)+A.getHeight()-(y1a-y1b));
		}else if((y0a > y0b) && (x0a <= x0b) && (x1a < x1b && x1a > x0b) && (y1a < y1b)){
			/*Caso:
			 *  	____________
			 *     |B		    |
			 *  ___|_____  	    |
			 * |A  |R    | 	    |
			 * |   |	 | 	    |
			 * |___|_____| 	    |
			 *     |____________|
			 * 
			 * */
			regionA.setBounds(x0b-x0a, 0,(x0b-x0a)+A.getWidth()-(x0b-x0a), A.getHeight());
			regionB.setBounds(0,y0a-y0b,A.getWidth()-(x0b-x0a),(y0a-y0b)+A.getHeight());
		}else if((y0a > y0b && y0a < y1b) && (x0a <= x0b) && (x1a < x1b && x1a > x0b) && (y1a >= y1b)){
			/*Caso:
			 *   	 ________
			 *		|B		 |
			 *		|		 |
			 *   ___|____    |
			 * 	|A	|R	 |	 | 
			 * 	|	|____|___|
			 * 	|________|
			 */
			regionA.setBounds(x0b-x0a, 0,(x0b-x0a)+A.getWidth()-(x0b-x0a), A.getHeight()-(y1a-y1b));
			regionB.setBounds(0,y0a-y0b,A.getWidth()-(x0b-x0a),(y0a-y0b)+A.getHeight()-(y1a-y1b));
		}else if((y0a > y0b) && (x0a <= x0b) && (x1a >= x1b) && (y1a < y1b)){
			/*Caso:
			 * 		_________
			 * 	   |B		 |
			 *  ___|_________|__
			 * |A  |R		 |	|
			 * |   |		 |	|
			 * |___|_________|__|
			 * 	   |_________|
			 * 
			 */
			regionA.setBounds(x0b-x0a, 0,(x0b-x0a)+A.getWidth()-(x1a-x1b),A.getHeight());
			regionB.setBounds(0,y0a-y0b,B.getWidth(),(y0a-y0b)+A.getHeight());
		}else if((y0a > y0b && y0a < y1b) && (x0a <= x0b) && (x1a >= x1b) && (y1a >= y1b)){
			/*Caso:
			 * 		_________
			 * 	   |B		 |
			 *  ___|_________|__
			 * |A  |R		 |	|
			 * |   |		 |	|
			 * |   |_________|	|
			 * |________________|
			 * 
			 */
			regionA.setBounds(x0b-x0a, 0,A.getWidth()-(x1a-x1b),A.getHeight()-(y1a - y1b));
			regionB.setBounds(0,y0a-y0b,B.getWidth(),B.getHeight());
		}else if((y0a <= y0b) && (x0a > x0b) && (x1a < x1b) && (y1a < y1b && y1b > y0a)){
			/*Caso:
			 * 		_________
			 * 	   |A		 |
			 *  ___|_________|__
			 * |B  |R		 |	|
			 * |   |		 |	|
			 * |   |_________|	|
			 * |________________|
			 * 
			 */
			regionA.setBounds(0, y0b-y0a, A.getWidth(),A.getHeight());
			regionB.setBounds(x0a-x0b,0,(x0a-x0b)+A.getWidth(),y1a-y0b);
		}else if((y0a <= y0b) && (x0a > x0b) && (x1a < x1b) && (y1a >= y1b)){
			/*Caso:
			 * 		_________
			 * 	   |A		 |
			 *  ___|_________|__
			 * |B  |R		 |	|
			 * |   |		 |	|
			 * |___|_________|__|
			 * 	   |_________|
			 * 
			 */
			regionA.setBounds(0, y0b-y0a, A.getWidth(),A.getHeight()-(y1a-y1b));
			regionB.setBounds(x0a-x0b,0,(x0a-x0b)+A.getWidth(),B.getHeight());
		}else if((y0a <= y0b && y1a > y0b) && (x0a > x0b && x0a < x1b) && (x1a >= x1b) && (y1a < y1b)){
			/*Caso:
			 *   	 ________
			 *		|A		 |
			 *		|		 |
			 *   ___|____    |
			 * 	|B	|R	 |	 | 
			 * 	|	|____|___|
			 * 	|________|
			 */
			regionA.setBounds(0, y0b-y0a, A.getWidth()-(x1a-x1b),A.getHeight());
			regionB.setBounds(x0a-x0b,0,B.getWidth(),y1a-y0b);
		}else if((y0a <= y0b) && (x0a > x0b && x0a < x1b) && (x1a >= x1b) && (y1a >= y1b)){
			/*Caso:
			 *  	____________
			 *     |A		    |
			 *  ___|_____  	    |
			 * |B  |R    | 	    |
			 * |   |	 | 	    |
			 * |___|_____| 	    |
			 *     |____________|
			 * 
			 * */
			regionA.setBounds(0, y1a-y0b, A.getWidth()-(x1a-x1b),A.getHeight()-(y1a-y1b));
			regionB.setBounds(x0a-x0b,0,B.getWidth(),B.getHeight());
		}else if((y0a <= y0b && y1a > y0b) && (x0a <= x0b && x1a > x0b) && (x1a < x1b) && (y1a < y1b)){
			/*Caso:
			 *  ________
			 * |A		|
			 * |	 ___|___
			 * |	|R	|  B|
			 * |	|	|	|
			 * |____|___|	|
			 * 		|		|
			 * 		|_______|
			 * */
			regionA.setBounds(x0b-x0a, y0b-y0a, A.getWidth(),A.getHeight());
			regionB.setBounds(0,0,B.getWidth()-(x1b-x1a),B.getHeight()-(y1b-y1a));
		}else if((y0a <= y0b) && (x0a <= x0b && x1a > x0b) && (x1a < x1b) && (y1a >= y1b)){
			/*Caso:
			 * 	____________
			 * |A			|
			 * |	   _____|___
			 * |	  |R	|  B|
			 * |	  |		|	|
			 * |	  |_____|___|
			 * |____________|
			 * 
			 * */
			regionA.setBounds(x0b-x0a, y0b-y0a, A.getWidth(),A.getHeight()-(y1a-y1b));
			regionB.setBounds(0,0,B.getWidth()-(x1b-x1a),B.getHeight());
		}else if((y0a <= y0b && y1a > y0b) && (x0a <= x0b) && (x1a >= x1b) && (y1a < y1b)){
			/*Caso:
			 *  ________________
			 * |A				|
			 * |  				|
			 * |				|
			 * |  __________	|
			 * | |R		 	|	|
			 * |_|__________|___|
			 *   |			|
			 *   |B			|
			 *   |__________|	
			 * 
			 * */
			//System.out.println("8.1");
			regionA.setBounds(x0b-x0a, y0b-y0a, A.getWidth()-(x1a-x1b),A.getHeight());
			regionB.setBounds(0,0,B.getWidth(),B.getHeight()-(y1b-y1a));
		}else if((y0a <= y0b) && (x0a <= x0b) && (x1a >= x1b) && (y1a >= y1b)){
			/*Caso:
			 *  ________________
			 * |A				|
			 * |  __________	|
			 * | |B = R 	|	|
			 * | |			|	|
			 * | |			|	|
			 * | |__________|	|
			 * |________________|
			 * 
			 * */
			regionA.setBounds(x0b-x0a, y0b-y0a, A.getWidth()-(x1a-x1b),A.getHeight()-(y1a-y1b));
			regionB.setBounds(0,0,B.getWidth(),B.getHeight());
		}else{
			return false;
		}
		for(int i = 0; i < regionA.getWidth(); i++){
			for(int j = 0; j < regionA.getHeight(); j++){
				if((A.getPixelAlpha(i + regionA.getX0(),j + regionA.getY0()) > 0)
						&&(B.getPixelAlpha(i + regionB.getX0(), j + regionB.getY0()) > 0)){

					return true;
				}
			}
		}
		return false;
	}
}
